using System.Linq.Expressions;

namespace ClassDemo.Repository;

/// <summary>
/// 通用Repository接口，定义基础CRUD操作
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
public interface IBaseRepository<T> where T : class, new()
{
    /// <summary>
    /// 根据ID获取实体
    /// </summary>
    /// <param name="id">主键ID</param>
    /// <returns>实体对象</returns>
    Task<T?> GetByIdAsync(object id);

    /// <summary>
    /// 获取所有实体
    /// </summary>
    /// <returns>实体列表</returns>
    Task<List<T>> GetAllAsync();

    /// <summary>
    /// 根据条件查询实体列表
    /// </summary>
    /// <param name="expression">查询条件</param>
    /// <returns>实体列表</returns>
    Task<List<T>> GetListAsync(Expression<Func<T, bool>> expression);

    /// <summary>
    /// 根据条件查询单个实体
    /// </summary>
    /// <param name="expression">查询条件</param>
    /// <returns>实体对象</returns>
    Task<T?> GetFirstAsync(Expression<Func<T, bool>> expression);

    /// <summary>
    /// 分页查询
    /// </summary>
    /// <param name="pageIndex">页码</param>
    /// <param name="pageSize">页大小</param>
    /// <param name="expression">查询条件</param>
    /// <returns>分页结果</returns>
    Task<(List<T> Data, int Total)> GetPageListAsync(int pageIndex, int pageSize, Expression<Func<T, bool>>? expression = null);

    /// <summary>
    /// 添加实体
    /// </summary>
    /// <param name="entity">实体对象</param>
    /// <returns>是否成功</returns>
    Task<bool> AddAsync(T entity);

    /// <summary>
    /// 批量添加实体
    /// </summary>
    /// <param name="entities">实体列表</param>
    /// <returns>是否成功</returns>
    Task<bool> AddRangeAsync(List<T> entities);

    /// <summary>
    /// 更新实体
    /// </summary>
    /// <param name="entity">实体对象</param>
    /// <returns>是否成功</returns>
    Task<bool> UpdateAsync(T entity);

    /// <summary>
    /// 批量更新实体
    /// </summary>
    /// <param name="entities">实体列表</param>
    /// <returns>是否成功</returns>
    Task<bool> UpdateRangeAsync(List<T> entities);

    /// <summary>
    /// 根据条件更新实体
    /// </summary>
    /// <param name="expression">更新条件</param>
    /// <param name="updateExpression">更新表达式</param>
    /// <returns>影响行数</returns>
    Task<int> UpdateAsync(Expression<Func<T, bool>> expression, Expression<Func<T, T>> updateExpression);

    /// <summary>
    /// 删除实体
    /// </summary>
    /// <param name="entity">实体对象</param>
    /// <returns>是否成功</returns>
    Task<bool> DeleteAsync(T entity);

    /// <summary>
    /// 根据ID删除实体
    /// </summary>
    /// <param name="id">主键ID</param>
    /// <returns>是否成功</returns>
    Task<bool> DeleteByIdAsync(object id);

    /// <summary>
    /// 根据条件删除实体
    /// </summary>
    /// <param name="expression">删除条件</param>
    /// <returns>影响行数</returns>
    Task<int> DeleteAsync(Expression<Func<T, bool>> expression);

    /// <summary>
    /// 检查实体是否存在
    /// </summary>
    /// <param name="expression">查询条件</param>
    /// <returns>是否存在</returns>
    Task<bool> ExistsAsync(Expression<Func<T, bool>> expression);

    /// <summary>
    /// 获取实体数量
    /// </summary>
    /// <param name="expression">查询条件</param>
    /// <returns>数量</returns>
    Task<int> CountAsync(Expression<Func<T, bool>>? expression = null);
}